package com.google.code.jholidays.io.xml;

import java.io.File;
import java.io.StringReader;

import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.xml.sax.SAXException;

/**
 * Represents xml schema validator which is used by {@link XmlReader} against
 * input xml files.
 * <p>
 * Subclass and override <tt>createSchema()</tt> method in order to use
 * different schema for validation
 * 
 * @author tillias
 * 
 */
public class XmlValidator {

    /**
     * Creates new instance of validator
     */
    public XmlValidator() {
	try {
	    validator = createValidator();
	} catch (SAXException e) {
	    validator = null;
	}
    }

    /**
     * Performs validation on input file against xml schema
     * 
     * @param f
     *            Input file to be validated
     * @return True if validation has succeeded, false otherwise
     */
    public boolean validate(File f) {
	boolean result = false;

	try {
	    validator.validate(new StreamSource(f));
	    result = true;
	} catch (Exception e) {
	    // nothing todo here
	}

	return result;
    }

    protected Validator createValidator() throws SAXException {
	Schema schema = createSchema();
	return schema.newValidator();
    }

    protected Schema createSchema() throws SAXException {
	String schemaStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
		+ "<schema xmlns=\"http://www.w3.org/2001/XMLSchema\" targetNamespace=\"http://www.example.org/DescriptorCollectionXml\" xmlns:tns=\"http://www.example.org/DescriptorCollectionXml\" elementFormDefault=\"qualified\">"
		+ "<element name=\"descriptors\" type=\"tns:DescriptorCollection\"></element>"
		+ "<complexType name=\"DescriptorCollection\">"
		+ "<sequence>"
		+ "<element name=\"descriptor\" type=\"tns:EventDescriptor\" maxOccurs=\"unbounded\" minOccurs=\"0\"></element>"
		+ "</sequence>"
		+ "</complexType>"
		+ "<complexType name=\"EventDescriptor\">"
		+ "<sequence>"
		+ "<element name=\"id\" type=\"int\" maxOccurs=\"1\" minOccurs=\"1\"></element>"
		+ "<element name=\"name\" type=\"string\" maxOccurs=\"1\" "
		+ "minOccurs=\"1\">"
		+ "</element>"
		+ "<element name=\"description\" type=\"string\" maxOccurs=\"1\" "
		+ "minOccurs=\"0\">"
		+ "</element>"
		+ "<element name=\"parent_id\" type=\"int\" maxOccurs=\"1\" "
		+ "minOccurs=\"0\">"
		+ "</element>"
		+ "<element name=\"expression\" type=\"string\" maxOccurs=\"1\" minOccurs=\"1\"></element>"
		+ "</sequence>" + "</complexType>" + "</schema>";
	SchemaFactory factory = SchemaFactory
		.newInstance("http://www.w3.org/2001/XMLSchema");

	return factory.newSchema(new StreamSource(new StringReader(schemaStr)));
    }

    Validator validator;

}
